/*
  This file is part of 'Trivial chess'.

  'Trivial chess' is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  'Trivial chess' is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with 'Trivial chess'.  If not, see <http://www.gnu.org/licenses/>.
*/

/* SVN FILE: $Id$ */
/**
 * @author         $Author$
 * @version        $Rev$
 * @lastrevision   $Date$
 * @filesource     $URL$
 */

//#define BOOST_TEST_MODULE Square
#include <boost/test/unit_test.hpp>
#include "../config.h"


BOOST_AUTO_TEST_SUITE( SquareTest )

const Square SQUARES[] = {
		Square::A1(), Square::B1(), Square::C1(), Square::D1(), Square::E1(), Square::F1(), Square::G1(), Square::H1(),
		Square::A2(), Square::B2(), Square::C2(), Square::D2(), Square::E2(), Square::F2(), Square::G2(), Square::H2(),
		Square::A3(), Square::B3(), Square::C3(), Square::D3(), Square::E3(), Square::F3(), Square::G3(), Square::H3(),
		Square::A4(), Square::B4(), Square::C4(), Square::D4(), Square::E4(), Square::F4(), Square::G4(), Square::H4(),
		Square::A5(), Square::B5(), Square::C5(), Square::D5(), Square::E5(), Square::F5(), Square::G5(), Square::H5(),
		Square::A6(), Square::B6(), Square::C6(), Square::D6(), Square::E6(), Square::F6(), Square::G6(), Square::H6(),
		Square::A7(), Square::B7(), Square::C7(), Square::D7(), Square::E7(), Square::F7(), Square::G7(), Square::H7(),
		Square::A8(), Square::B8(), Square::C8(), Square::D8(), Square::E8(), Square::F8(), Square::G8(), Square::H8(),
		Square::NIL()
	};

const char* SQUARES_STR[] =  {
		"a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1",
		"a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2",
		"a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3",
		"a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4",
		"a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5",
		"a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6",
		"a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7",
		"a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8",
		"-"
	};

const int SQUARES_LENGTH = 65;

BOOST_AUTO_TEST_CASE( testRank ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square = SQUARES[i];
		BOOST_CHECK_EQUAL(square.rank().toInt(),(i / 8));
	}
}

BOOST_AUTO_TEST_CASE( testFile ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square = SQUARES[i];
		BOOST_CHECK_EQUAL(square.file().toInt(),(i % 8));
	}
}

BOOST_AUTO_TEST_CASE( testSetRank ) {
	for ( int f = 0; f < 8; ++f ) {
		Square square = SQUARES[f];
		File file = File(f);
		for ( int r = 0; r < 8; ++r ) {
			Rank rank = Rank(r);
			square.setRank( rank );
			BOOST_CHECK_EQUAL(square.rank(), rank);
			BOOST_CHECK_EQUAL(square.file(), file);
		}
	}
}

BOOST_AUTO_TEST_CASE( testSetFile ) {
	for ( int r = 0; r < 8; ++r ) {
		Square square = SQUARES[r * 8];
		Rank rank = Rank(r);
		for ( int f = 0; f < 8; ++f ) {
			File file = File(f);
			square.setFile( file );
			BOOST_CHECK_EQUAL(square.file(), file);
			BOOST_CHECK_EQUAL(square.rank(), rank);
		}
	}
}


BOOST_AUTO_TEST_CASE( fromFileAndRank ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Rank rank;
		rank.fromInt(i/8);
		File file;
		file.fromInt(i%8);
		Square square;
		square.fromFileAndRank(file, rank);
		BOOST_CHECK_EQUAL(square, SQUARES[i]);
	}
}

BOOST_AUTO_TEST_CASE( testSquare_File_Rank ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Rank rank;
		rank.fromInt(i/8);
		File file;
		file.fromInt(i%8);
		Square square =  Square(file, rank);
		BOOST_CHECK_EQUAL(square, SQUARES[i]);
	}
}

BOOST_AUTO_TEST_CASE( testEqual ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square = SQUARES[i];
		BOOST_CHECK_EQUAL(square, SQUARES[i]);
	}
}

BOOST_AUTO_TEST_CASE( testNotEqual ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square1 = SQUARES[i];
		for ( int j = 0; j < 7; ++j ) {
			Square square2 = SQUARES[j];
			if ( i != j )
				BOOST_CHECK_NE(square1, square2);
		}
	}
}


BOOST_AUTO_TEST_CASE( testSquare_Int ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square = Square(i);
		BOOST_CHECK_EQUAL(square, SQUARES[i]);
	}
}

BOOST_AUTO_TEST_CASE( testToInt ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square = SQUARES[i];
		BOOST_CHECK_EQUAL(square.toInt(), i);
	}
}

BOOST_AUTO_TEST_CASE( testFromInt ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square;
		square.fromInt(i);
		BOOST_CHECK_EQUAL(square, SQUARES[i]);
	}
}

BOOST_AUTO_TEST_CASE( testInc ) {
	int i = 0;
	Square square = Square::BEGIN();
	while ( i < SQUARES_LENGTH - 1 ) {
		BOOST_CHECK_EQUAL(SQUARES[i], square);
		++square;
		++i;
	}
	BOOST_CHECK_EQUAL(square, Square::END());
}

BOOST_AUTO_TEST_CASE( testDec ) {
	int i = SQUARES_LENGTH - 2;
	Square square = Square::RBEGIN();
	while ( i >= 0 ) {
		BOOST_CHECK_EQUAL(SQUARES[i], square);
		--square;
		--i;
	}

	BOOST_CHECK_EQUAL(square, Square::REND());
}

BOOST_AUTO_TEST_CASE( toStrTest ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square = SQUARES[i];

		BOOST_CHECK_EQUAL(square.toStr(), SQUARES_STR[i]);
	}
}

BOOST_AUTO_TEST_CASE( fromStrTest ) {
	for ( int i = 0; i < SQUARES_LENGTH; ++i ) {
		Square square;
		square.fromStr(SQUARES_STR[i]);

		BOOST_CHECK_EQUAL(square, SQUARES[i]);
	}
}

BOOST_AUTO_TEST_SUITE_END()
